use crate::interpreter::value::Value;
use std::fmt::Debug;
use std::rc::Rc;

/// 方法类型枚举\
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MethodType {
    /// 数字类型方法
    Number,
    /// 字符串类型方法
    String,
    /// 布尔类型方法
    Boolean,
    /// 列表类型方法
    List,
    /// 字典类型方法
    Dict,
    /// 集合类型方法
    Set,
    /// 元组类型方法
    Tuple,
    /// 函数类型方法
    Function,
    /// 对象类型方法
    Object,
    /// 通用方法
    Generic,
    /// 任意类型
    Any,
    /// 空值类型
    Null,
}

/// 方法定义
pub struct Method {
    /// 方法类型
    pub method_type: MethodType,
    /// 方法实现
    pub implementation: Rc<dyn Fn(&[Value]) -> Result<Value, String>>,
}

impl Method {
    /// 创建一个新的本地方法
    pub fn native<T: Fn(&[Value]) -> Result<Value, String> + 'static>(
        method_type: MethodType,
        func: T,
    ) -> Self {
        Method {
            method_type,
            implementation: Rc::new(func),
        }
    }

    /// 调用方法
    pub fn call(&self, args: &[Value]) -> Result<Value, String> {
        (self.implementation)(args)
    }
}

impl Debug for Method {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Method")
            .field("method_type", &self.method_type)
            .field("implementation", &"<function>")
            .finish()
    }
}

impl Clone for Method {
    fn clone(&self) -> Self {
        Method {
            method_type: self.method_type.clone(),
            implementation: Rc::clone(&self.implementation),
        }
    }
}

impl PartialEq for Method {
    fn eq(&self, other: &Self) -> bool {
        self.method_type == other.method_type
        // 简化实现，不比较函数指针
    }
}
